package com.jake.xfeed.recyclerfeed;

import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;

public class HeaderFooterFeedAdapter<Data> extends RecyclerViewFeedAdapter<Data> {
    private static final int VIEW_TYPE_HEADER = -112121;
    private static final int VIEW_TYPE_FOOTER = -112122;
    private HeaderFooterContainer mHeaderView;
    private HeaderFooterContainer mFooterView;
    private boolean mIsAttachedToRecyclerView = false;

    public HeaderFooterFeedAdapter(@NonNull IDataSource<Data> dataSource) {
        super(dataSource);
    }

    public void setHeaderView(HeaderFooterContainer headerView) {
        this.mHeaderView = headerView;
        if (mIsAttachedToRecyclerView) {
            notifyDataSetChanged();
        }
    }

    public void setFooterView(HeaderFooterContainer footerView) {
        this.mFooterView = footerView;
        if (mIsAttachedToRecyclerView) {
            notifyDataSetChanged();
        }
    }

    public boolean hasHeader() {
        return mHeaderView != null;
    }

    private ListUpdateCallback mListUpdateCallback;

    public ListUpdateCallback getListUpdateCallback() {
        if (mListUpdateCallback == null) {
            mListUpdateCallback = new ListUpdateCallback() {
                @Override
                public void onInserted(int position, int count) {
                    if (hasHeader()) {
                        position++;
                    }
                    notifyItemRangeInserted(position, count);
                }

                @Override
                public void onRemoved(int position, int count) {
                    if (hasHeader()) {
                        position++;
                    }
                    notifyItemRangeRemoved(position, count);
                }

                @Override
                public void onMoved(int fromPosition, int toPosition) {
                    if (hasHeader()) {
                        fromPosition++;
                        toPosition++;
                    }
                    notifyItemMoved(fromPosition, toPosition);
                }

                @Override
                public void onChanged(int position, int count, @Nullable Object payload) {
                    if (hasHeader()) {
                        position++;
                    }
                    notifyItemRangeChanged(position, count, payload);
                }
            };
        }
        return mListUpdateCallback;
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        mIsAttachedToRecyclerView = true;
    }

    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        mIsAttachedToRecyclerView = false;
    }

    @NonNull
    @Override
    public FeedViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_HEADER && mHeaderView != null) {
            return new FeedViewHolder(mHeaderView);
        }
        if (viewType == VIEW_TYPE_FOOTER && mFooterView != null) {
            return new FeedViewHolder(mFooterView);
        }

        return super.onCreateViewHolder(parent, viewType);
    }

    @Override
    public void onBindViewHolder(@NonNull FeedViewHolder holder, int position) {
        if (holder.card == mHeaderView || holder.card == mFooterView) {
            holder.card.bind(position, null);
            return;
        }
        if (mHeaderView != null) {
            position--;
        }
        super.onBindViewHolder(holder, position);
    }

    @Override
    public int getItemViewType(int position) {
        if (mHeaderView != null && position == 0) {
            return VIEW_TYPE_HEADER;
        }
        if (mFooterView != null && position == getItemCount() - 1) {
            return VIEW_TYPE_FOOTER;
        }
        if (mHeaderView != null) {
            position--;
        }
        return super.getItemViewType(position);
    }

    @Override
    public int getItemCount() {
        int count = super.getItemCount();
        if (mHeaderView != null) {
            count++;
        }
        if (mFooterView != null) {
            count++;
        }
        return count;
    }

}
